#define JMBC_INSIDE
#include "tcCheckPoints.h"
#include <Math/mlMath.h>
#include <Core/clCore.h>
#include <stdio.h>
#include <string.h>

#define chpsg(g) checkpoints->groups[TC_CHECKPOINTS_GROUP_ ## g]
#define chpss(t) sizeof(TCCheckPoints ## t)

// Context

#define STORE ID_SMALL_STORE

static TCCheckPoints *store[STORE];

void
tcCheckPointsCreateContext(void)
{
	idClearStore(TCCheckPoints, STORE, store);
}

// Generation / Deletion

static
void
Init(TCCheckPoints *checkpoints)
{
}

static
void
Term(TCCheckPoints *checkpoints)
{
}

void
tcGenCheckPointses(unsigned int n, unsigned int *checkpointses)
{
	idGenObjects(TCCheckPoints, STORE, store, Init, n, checkpointses);
}

void
tcDeleteCheckPointses(unsigned int n, unsigned int *checkpointses)
{
	idDeleteObjects(store, Term, n, checkpointses);
}

// Load / Unload

void
tcCheckPointsLoad(unsigned int id, unsigned int filepath)
{
	FILE *stream;
	char tmp[256];

	//stream = _wfopen(tlStringData(filepath), L"rb");
	wcstombs(tmp, tlStringData(filepath), 256);
	stream = fopen(tmp, "rb");

	if(stream)
	{
		TCCheckPoints *checkpoints;
		TCCheckPointsHeader header;

		checkpoints = store[id];

		fread(&header, 1, chpss(Header), stream);

		tlGenGroups(1, checkpoints->groups);

		tlGroupRead(chpsg(VERTICES), header.vertices, chpss(Vertex), stream);

		fclose(stream);
	}
	else
		elErrorSet(EL_ERROR_INVALID);
}

void
tcCheckPointsUnload(unsigned int id)
{
	TCCheckPoints *checkpoints;

	checkpoints = store[id];

	tlDeleteGroups(1, checkpoints->groups);
}

void
tcCheckPointssUnload(unsigned int n, unsigned int *checkpointses)
{
	unsigned int i;

	for(i = 0; i < n; i++)
		tcCheckPointsUnload(checkpointses[i]);
}

// Operation

void
tcCheckPointsCompile(unsigned int id, unsigned int filepath)
{
	FILE *stream;
	char tmp[256];

	//stream = _wfopen(tlStringData(filepath), L"r");
	wcstombs(tmp, tlStringData(filepath), 256);
	stream = fopen(tmp, "r");

	if(stream)
	{
		TCCheckPoints *checkpoints;
		TCCheckPointsHeader header;
		TCCheckPointsVertex *vertices;
		wchar_t buffer[512];
		unsigned int i;

		checkpoints = store[id];

		tlGenGroups(1, checkpoints->groups);

		fgetws(buffer, 512, stream);
		swscanf(buffer, L"vertices %i", &header.vertices);

		wprintf(L"Vertices: %i\n", header.vertices);

		tlGroupAllocate(chpsg(VERTICES), header.vertices, chpss(Vertex));
		vertices = tlGroupArray(chpsg(VERTICES));

		for(i = 0; i < header.vertices; i++)
		{
			fgetws(buffer, 512, stream);
			swscanf(buffer, L"coord %f %f %f", &vertices[i].coord[0], &vertices[i].coord[1], &vertices[i].coord[2]);
		}


		fclose(stream);
	}
	else
		elErrorSet(EL_ERROR_INVALID);
}

void
tcCheckPointsDecompile(unsigned int id, unsigned int filepath)
{
	FILE *stream;
	char tmp[256];

	//stream = _wfopen(tlStringData(filepath), L"w");
	wcstombs(tmp, tlStringData(filepath), 256);
	stream = fopen(tmp, "w");

	if(stream)
	{
		TCCheckPoints *checkpoints;
		TCCheckPointsHeader header;
		TCCheckPointsVertex *vertices;
		unsigned int i;

		checkpoints = store[id];

		header.vertices = tlGroupLength(chpsg(VERTICES));
		vertices = tlGroupArray(chpsg(VERTICES));

		fwprintf(stream, L"vertices %i\n", header.vertices);

		for(i = 0; i < header.vertices; i++)
		{
			fwprintf(stream, L"coord %f %f %f\n", vertices[i].coord[0], vertices[i].coord[1], vertices[i].coord[2]);

		}


		fclose(stream);
	}
	else
		elErrorSet(EL_ERROR_INVALID);
}

unsigned int
tcCheckPointsVertices(unsigned int id)
{
	TCCheckPoints *checkpoints;

	checkpoints = store[id];

	return tlGroupLength(chpsg(VERTICES));
}

float *
tcCheckPointsVertex(unsigned int id, unsigned int vertex)
{
	TCCheckPoints *checkpoints;
	TCCheckPointsVertex *vertices;

	checkpoints = store[id];

	vertices = tlGroupArray(chpsg(VERTICES));

	return vertices[vertex].coord;
}

// Disk I/O

void
tcCheckPointsSave(unsigned int id, unsigned int filepath)
{
	FILE *stream;
	char tmp[256];

	//stream = _wfopen(tlStringData(filepath), L"wb");
	wcstombs(tmp, tlStringData(filepath), 256);
	stream = fopen(tmp, "wb");

	if(stream)
	{
		TCCheckPoints *checkpoints;
		TCCheckPointsHeader header;

		checkpoints = store[id];

		header.vertices = tlGroupLength(chpsg(VERTICES));

		fwrite(&header, 1, chpss(Header), stream);

		tlGroupWrite(chpsg(VERTICES), stream);

		fclose(stream);
	}
	else
		elErrorSet(EL_ERROR_INVALID);
}
